#include "Stdafx.h"

#include "Application.h"

#include "../render/RenderSwapChain.h"
#include "../game/RenderMgr.h"
#include "Timer.h"

namespace WindGE
{
	Application::Application()
		: app_name_(L"")
		, hwnd_(0)
		, client_width_(0.0f)
		, client_height_(0.0f)
		, frame_count_(0)
		, is_paused_(false)
	{
	}

	Application::~Application()
	{
	}

	bool Application::init(RenderDevicePtr renderDevice, HWND hwnd, float width, float height)
	{
		hwnd_ = hwnd;
		client_width_ = width;
		client_height_ = height;
		render_device_ = renderDevice;

		swap_chain_ = std::make_shared<RenderSwapChain>();
		
		RenderSwapChainDesc swapchainDesc;
		
		swapchainDesc.en4xMsaa = false;
		swapchainDesc.format = DXGI_FORMAT_R8G8B8A8_UNORM;
		swapchainDesc.isWindowed = true;
		swapchainDesc.swapChainFlags = 0;
		swapchainDesc.swapEffect = DXGI_SWAP_EFFECT_DISCARD;
		swapchainDesc.usage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT;
		swapchainDesc.windowHandle = hwnd;
		swapchainDesc.windowHeight = (int)height;
		swapchainDesc.windowWidth = (int)width;
		
		if (!swap_chain_->init(render_device_, swapchainDesc)) return false;
		if (!swap_chain_->refresh(render_device_, (unsigned int)width, (unsigned int)height)) return false;

		if (!on_init()) return false;

		return true;
	}

	void Application::resize(float width, float height)
	{
		client_width_ = width;
		client_height_ = height;

		if (!swap_chain_->refresh(render_device_, (unsigned int)width, (unsigned int)height)) return;

		on_resize();
	}

	void Application::render()
	{
		Timer::Instance().tick();

		if (!is_paused_)
		{
			on_update();
			on_draw();
		}
		else
		{
			Sleep(100);
		}
	}

	void Application::start()
	{
		is_paused_ = false;
		Timer::Instance().reset();
	}

	void Application::pause()
	{
		is_paused_ = true;
		Timer::Instance().stop();
	}

	void Application::resume()
	{
		is_paused_ = false;
		Timer::Instance().start();
	}

	void Application::begin_scene(const XMVECTORF32& color)
	{
		swap_chain_->set_back_render_target();
		swap_chain_->clear_back_render_target(reinterpret_cast<const float*>(&color));
	}

	void Application::begin_scene(const float* color)
	{
		swap_chain_->set_back_render_target();
		swap_chain_->clear_back_render_target(color);
	}

	void Application::end_scene(bool isFixedFps /* = false */)
	{
		swap_chain_->present(isFixedFps);
	}

}//end namespace WindGE
